#include "ventana.h"
#include "ui_ventana.h"
#include <math.h>
#include<QMessageBox>
Ventana::Ventana(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::VentanaClass)
{
    ui->setupUi(this);
    ui->GrayWidget->v=this;
    ui->RedWidget->v=this;
    ui->BlueWidget->v=this;
    ui->GreenWidget->v=this;
    memset(R,0,sizeof(R));
    memset(G,0,sizeof(G));
    memset(B,0,sizeof(B));
    memset(gray,0,sizeof(gray));
    k = new Kernels();
    r = new rotation();
    k->paint=ui->Image;
    k->v=this;
    r->v=this;
}

Ventana::~Ventana()
{
    delete ui;
}

void Ventana::on_ApplyNegative_clicked()
{
    QVector<QRgb> Paleta=ui->Image->image.colorTable();
    for(int i=0;i<256;i++)
    {
        QColor color(Paleta[i]);
        color.setRed(255-color.red());
        color.setGreen(255-color.green());
        color.setBlue(255-color.blue());
        Paleta[i]=color.rgb();
    }
    ui->Image->image.setColorTable(Paleta);
    ui->Image->update();
    getHistogram();

}

void Ventana::on_actionExit_triggered()
{
    exit(0);
}

void Ventana::getHistogram()
{
    ui->Image->setGeometry(0,0,ui->Image->image.width(),ui->Image->image.height());
    QVector<QRgb> Paleta=ui->Image->image.colorTable();
    if(Paleta.size()<256){
        int top=Paleta[Paleta.size()-1];
        for(int i=Paleta.size();i<=256;++i){
            Paleta.push_back(top);
        }
        ui->Image->image.setColorTable(Paleta);
    }
    memset(R,0,sizeof(R));
    memset(G,0,sizeof(G));
    memset(B,0,sizeof(B));
    memset(gray,0,sizeof(gray));

    for(int x=0;x<ui->Image->image.width();++x){
        for(int y=0;y<ui->Image->image.height();++y){
            QColor co(Paleta[ui->Image->image.pixelIndex(x,y)]);
            R[co.red()]++;
            G[co.green()]++;
            B[co.blue()]++;
            gray[(co.red()+co.green()+co.blue())/3]++;
        }
    }
    maR=maG=maB=maGray=0;
    for(int i=0;i<256;++i)
    {
       maR=std::max(maR,R[i]);
       maG=std::max(maG,G[i]);
       maB=std::max(maB,B[i]);
       maGray=std::max(maGray,gray[i]);
    }
    ui->GrayWidget->update();
    ui->RedWidget->update();
    ui->GreenWidget->update();
    ui->BlueWidget->update();
}

void Ventana::on_actionOpen_triggered()
{
    QString dir = QFileDialog::getOpenFileName(this,tr("Open Image"),"","Image (*.bmp *.jpg *.png *.gif *.jpeg)");

    if(dir!=QString::null){
        QImage tmp;
        if(tmp.load(dir)){
            if(tmp.colorTable().size()==0){
                QMessageBox::warning(this,"Warning","Image is not 8bit, was converted to 8bit image...");
                QVector<QRgb> ByN(256);
                for(int i=0;i<256;++i) ByN[i]=QColor(i,i,i,255).rgb();
                tmp=tmp.convertToFormat(QImage::Format_Indexed8,ByN);
             }
            /*if(tmp.colorTable().size()!=256){
                QVector<QRgb> v(tmp.colorTable());
                v.resize(256);
                tmp.setColorTable(v);
            }*/
            ui->SourceImage->image=tmp;
            ui->Image->image=tmp;
            ui->SourceImage->update();
            ui->Image->update();

            getHistogram();
        }

    }
}

void Ventana::on_ApplyEqualize_clicked()
{
    QVector<double> AcumuladaRed(256,0.0);
    QVector<double> AcumuladaGreen(256,0.0);
    QVector<double> AcumuladaBlue(256,0.0);

    QVector<int> ProbRed(256);
    QVector<int> ProbGreen(256);
    QVector<int> ProbBlue(256);

    AcumuladaRed[0]=R[0];
    AcumuladaGreen[0]=G[0];
    AcumuladaBlue[0]=B[0];
    for(int i=1;i<256;++i)
    {
        AcumuladaRed[i]=AcumuladaRed[i-1]+R[i];
        AcumuladaGreen[i]=AcumuladaGreen[i-1]+G[i];
        AcumuladaBlue[i]=AcumuladaBlue[i-1]+B[i];
    }
    QVector<QRgb> Paleta=ui->Image->image.colorTable();
    for(int i=0;i<256;i++)
    {
            ProbBlue[i]=int((AcumuladaBlue[i]/AcumuladaBlue[255])*255);
            ProbGreen[i]=int((AcumuladaGreen[i]/AcumuladaGreen[255])*255);
            ProbRed[i]=int((AcumuladaRed[i]/AcumuladaRed[255])*255);
            if(ProbBlue[i]<0)ProbBlue[i]=0;
            if(ProbGreen[i]<0)ProbGreen[i]=0;
            if(ProbRed[i]<0)ProbRed[i]=0;
            if(ProbBlue[i]>255)ProbBlue[i]=255;
            if(ProbGreen[i]>255)ProbGreen[i]=255;
            if(ProbRed[i]>255)ProbRed[i]=255;
            Paleta[i]=QColor(ProbRed[i],ProbGreen[i],ProbBlue[i]).rgb();
    }
    ui->Image->image.setColorTable(Paleta);
    ui->Image->update();
    getHistogram();
}

void Ventana::on_ApplyBrightness_clicked()
{
    QVector<QRgb> Paleta=ui->Image->image.colorTable();
    for(int i=0;i<256;i++)
    {
        QColor color(Paleta[i]);
        color.setRed(color.red()+ui->BrightnessSlider->value());
        color.setGreen(color.green()+ui->BrightnessSlider->value());
        color.setBlue(color.blue()+ui->BrightnessSlider->value());
        Paleta[i]=color.rgb();
    }
    ui->Image->image.setColorTable(Paleta);
    ui->Image->update();
    getHistogram();

}

void Ventana::on_ApplyGamma_clicked()
{
    double gamma=ui->GammaSpinBox->value();
    QVector<QRgb> Paleta=ui->Image->image.colorTable();
    for(int i=0;i<256;++i)
    {
        QColor color(Paleta[i]);
        color.setRed((int)(pow(color.redF(),1.0/gamma)*255.0));
        color.setGreen((int)(pow(color.greenF(),1.0/gamma)*255.0));
        color.setBlue((int)(pow(color.blueF(),1.0/gamma)*255.0));
        Paleta[i]=color.rgb();
    }

    ui->Image->image.setColorTable(Paleta);
    ui->Image->update();
    getHistogram();
}

void Ventana::on_actionAdd_Image_triggered()
{
    QString dir = QFileDialog::getOpenFileName(this,tr("Add Image"),"","Image (*.bmp *.jpg *.png *.gif *.jpeg)");

    if(dir!=QString::null){
        QImage tmp;
        int aux;
        if(tmp.load(dir)){
            if(tmp.colorTable().size()>0 && tmp.size()==ui->Image->image.size())
            {
                for(int x=0;x<ui->Image->image.width();++x){
                    for(int y=0;y<ui->Image->image.height();++y){
                        aux=ui->Image->image.pixelIndex(x,y)+tmp.pixelIndex(x,y);
                        if(aux>255) aux=255;
                        else if(aux<0) aux=0;
                        ui->Image->image.setPixel(x,y,aux);
                    }
                }
                ui->Image->update();
                getHistogram();
            }else{

            }
        }

    }

}

void Ventana::on_actionSubstract_Image_triggered()
{
    QString dir = QFileDialog::getOpenFileName(this,tr("Add Image"),"","Image (*.bmp *.jpg *.png *.gif *.jpeg)");

    if(dir!=QString::null){
        QImage tmp;
        int aux;
        if(tmp.load(dir)){
            if(tmp.colorTable().size()>0 && tmp.size()==ui->Image->image.size())
            {
                for(int x=0;x<ui->Image->image.width();++x){
                    for(int y=0;y<ui->Image->image.height();++y){
                        aux=ui->Image->image.pixelIndex(x,y)-tmp.pixelIndex(x,y);
                        if(aux>255) aux=255;
                        else if(aux<0) aux=0;
                        ui->Image->image.setPixel(x,y,aux);
                    }
                }
                ui->Image->update();
                getHistogram();
            }else{

            }
        }

    }
}

void Ventana::on_actionFilter_Mask_triggered()
{
    QString dir = QFileDialog::getOpenFileName(this,tr("Add Image"),"","Image (*.bmp *.jpg *.png *.gif *.jpeg)");

    if(dir!=QString::null){
        QImage tmp;
        int aux;
        if(tmp.load(dir)){
            if(tmp.colorTable().size()>0 && tmp.size()==ui->Image->image.size())
            {
                for(int x=0;x<ui->Image->image.width();++x){
                    for(int y=0;y<ui->Image->image.height();++y){
                        int ind=tmp.pixelIndex(x,y);
                        if(ind>128) ind=1;
                        else ind=0;
                        aux=ui->Image->image.pixelIndex(x,y)*ind;
                        ui->Image->image.setPixel(x,y,aux);
                    }
                }
                ui->Image->update();
                getHistogram();
            }else{

            }
        }

    }

}

void Ventana::on_ApplyThreshold_clicked()
{
    /*int canals=ui->ThresholdSpinBox->value();
    int rango=256/canals;
    QVector<QRgb> Paleta=ui->Image->image.colorTable();
    QVector<QRgb> colors=ui->Image->image.colorTable();
   // QColor color(Paleta[ui->Image->image.pixelIndex(x,y)]);
    if(rango%canals!=0) rango++;
    for(int i=0;i<canals;i++)
    {
        for(int j=0;j<rango && i*rango+j<=255;j++)
        {
            Paleta[i*rango+j]=colors[i*rango];
        }
    }
    ui->Image->image.setColorTable(Paleta);*/
    QVector<QRgb> tb=ui->Image->image.colorTable();
    int d=256/ui->ThresholdSpinBox->value();
    int ind=255 - d;
    QRgb ultc=tb[0];
    //int dif=d*
    for(int i=0;i<tb.size();++i){
        if(i>=ind) ultc=tb[255];
        else if(i%d==0) ultc=tb[i];
        tb[i]=ultc;
    }
    ui->Image->image.setColorTable(tb);
    ui->Image->update();
    getHistogram();

}

void Ventana::on_ApplyContrast_clicked()
{
       int cont=-1*ui->ContrastSlider->value();
        QVector<QRgb> tb=ui->Image->image.colorTable();
        QVector<QRgb> cp=ui->Image->image.colorTable();
        float camb=float(256-cont*2)/float(256);
        float acum=camb;
        for(int i=0;i<256;++i){
            int n=cont+int(acum);
            if(n>255) n=255;
            if(n<0) n=0;
            tb[i]=cp[n];
            acum+=camb;
        }
        ui->Image->image.setColorTable(tb);
        ui->Image->update();
        getHistogram();

 }

void Ventana::on_actionGrey_Scale_triggered()
{
    QVector<QRgb> Paleta=ui->Image->image.colorTable();
    int gray;
    for(int x=0;x<Paleta.size();++x){
        QColor color(Paleta[x]);
        gray = (color.red()+color.green()+color.blue())/3;
        color.setRed(gray);
        color.setGreen(gray);
        color.setBlue(gray);
        Paleta[x]=color.rgb();
    }

    ui->Image->image.setColorTable(Paleta);
    ui->Image->update();
    getHistogram();

}

void Ventana::on_actionConvolution_triggered()
{
    k->show();
}

void Ventana::on_actionCMYK_RGB_triggered()
{
    QVector<QRgb> Paleta=ui->Image->image.colorTable();
    float c, m, y, k;

    for(int i=0;i<256;i++)
    {
        QColor color(Paleta[i]);

        c=1.0f-color.redF();
        m=1.0f-color.greenF();
        y=1.0f-color.blueF();
        k=std::min(c,std::min(y,m));
        if(k==1.0f){
            c=m=y=0.0f;
        }else{
            c = (c-k)/(1.0f - k);
            m = (m-k)/(1.0f - k);
            y = (y-k)/(1.0f - k);
        }

        color.setRedF((1.0f-c)*(1.0f-k));
        color.setGreenF((1.0f-m)*(1.0f-k));
        color.setBlueF((1.0f-y)*(1.0f-k));
        Paleta[i]=color.toCmyk().rgb();
    }
    ui->Image->image.setColorTable(Paleta);
    ui->Image->update();
    getHistogram();

}

void Ventana::on_actionVertical_Flip_triggered()
{
    for(int x=0;x<ui->Image->image.width();++x){
        for(int y=0;y<ui->Image->image.height()/2;++y){
            int pix=ui->Image->image.pixelIndex(x,y);
            ui->Image->image.setPixel(x,y,ui->Image->image.pixelIndex(x,ui->Image->image.height()-y));
            ui->Image->image.setPixel(x,ui->Image->image.height()-y,pix);
        }
    }
    ui->Image->update();
    getHistogram();
}

void Ventana::on_actionFlip_triggered()
{
    for(int x=0;x<ui->Image->image.width()/2;++x){
        for(int y=0;y<ui->Image->image.height();++y){
            int pix=ui->Image->image.pixelIndex(x,y);
            ui->Image->image.setPixel(x,y,ui->Image->image.pixelIndex(ui->Image->image.width()-x,y));
            ui->Image->image.setPixel(ui->Image->image.width()-x,y,pix);
        }
    }
    ui->Image->update();
    getHistogram();
}

void Ventana::on_actionRotate_triggered()
{
  //    int x2,y2;
    r->img=&(ui->Image->image);
    r->show();
    ui->Image->update();
    getHistogram();

}

void Ventana::on_action_Save_triggered()
{
   if(!ui->Image->image.isNull()){
        QString s=QFileDialog::getSaveFileName(this, tr("Save File"),"", tr("Image BMP (*.bmp)"));
        if(!s.isNull()){
            if(ui->Image->image.save(s,"BMP"))
            QMessageBox::information(this,"Save...","Image Saved...");
            else QMessageBox::information(this,"Save...","Error...");
        }

    }
}

void Ventana::on_action0_25x_triggered()
{
    //ui->Image->aux=ui->Image->image;
    QImage img(ui->Image->image.width()/4,ui->Image->image.height()/4,ui->Image->image.format());
    img.setColorTable(ui->Image->image.colorTable());
    for(int i=0;i<img.width();i++)
    {
        for(int j=0;j<img.height();j++)
        {
            int prom=0;
            for(int x=i*4;x<i*4+4;x++)
            {
                for(int y=j*4;y<j*4+4;y++)
                {
                    prom+=ui->Image->image.pixelIndex(x,y);
                }
            }
            img.setPixel(i,j,prom/16);
        }
    }
    ui->Image->image=img;
    ui->Image->update();
    getHistogram();

}

void Ventana::on_action0_5x_triggered()
{
    QImage img(ui->Image->image.width()/2,ui->Image->image.height()/2,ui->Image->image.format());
    img.setColorTable(ui->Image->image.colorTable());
    for(int i=0;i<img.width();i++)
    {
        for(int j=0;j<img.height();j++)
        {
            int prom=0;
            for(int x=i*2;x<i*2+2;x++)
            {
                for(int y=j*2;y<j*2+2;y++)
                {
                    prom+=ui->Image->image.pixelIndex(x,y);
                }
            }
            img.setPixel(i,j,prom/4);
        }
    }
    ui->Image->image=img;
    ui->Image->update();
    getHistogram();
}

void Ventana::on_action2x_triggered()
{
    QImage img(ui->Image->image.width()*2,ui->Image->image.height()*2,ui->Image->image.format());
    img.setColorTable(ui->Image->image.colorTable());
    for(int i=0;i<ui->Image->image.width();i++)
    {
        for(int j=0;j<ui->Image->image.height();j++)
        {
            for(int x=i*2;x<i*2+2;x++)
            {
                for(int y=j*2;y<j*2+2;y++)
                {
                    img.setPixel(x,y,ui->Image->image.pixelIndex(i,j));
                }
            }
        }
    }
    ui->Image->image=img;
    int mat[7][7]={{1,1,1,0,0,0,0},
                   {1,1,1,0,0,0,0},
                   {1,1,1,0,0,0,0},
                   {0,0,0,0,0,0,0},
                   {0,0,0,0,0,0,0},
                   {0,0,0,0,0,0,0},
                   {0,0,0,0,0,0,0}};
    k->convolution(mat,3,false);

    ui->Image->update();
    getHistogram();
}

void Ventana::on_action4x_triggered()
{
    QImage img(ui->Image->image.width()*4,ui->Image->image.height()*4,ui->Image->image.format());
    img.setColorTable(ui->Image->image.colorTable());
    for(int i=0;i<ui->Image->image.width();i++)
    {
        for(int j=0;j<ui->Image->image.height();j++)
        {
            for(int x=i*4;x<i*4+4;x++)
            {
                for(int y=j*4;y<j*4+4;y++)
                {
                    img.setPixel(x,y,ui->Image->image.pixelIndex(i,j));
                }
            }
        }
    }
    ui->Image->image=img;
    int mat[7][7]={{1,1,1,0,0,0,0},
                   {1,1,1,0,0,0,0},
                   {1,1,1,0,0,0,0},
                   {0,0,0,0,0,0,0},
                   {0,0,0,0,0,0,0},
                   {0,0,0,0,0,0,0},
                   {0,0,0,0,0,0,0}};
    k->convolution(mat,3,false);

    ui->Image->update();
    getHistogram();
}

void Ventana::on_actionMin_Filter_triggered()
{
    /*for(int x=0;ui->Image->image.width();++x)
    {
        for(int y=0;ui->Image->image.height();++y)
        {
            int min=256;
            for(int i=x*3;i<x*3+3;i++)
            {
                for(int j=y*3;j<y*3+3;j++)
                {
                    if(ui->Image->image.pixelIndex(x,y)<min) min=ui->Image->image.pixelIndex(x,y);
                }
            }
            ui->Image->image.setPixel(x,y,min);
        }
    }*/
    k->filter(2);
    //ui->Image->update();
   // getHistogram();
}

void Ventana::on_actionMax_Filter_triggered()
{
    k->filter(0);
}

void Ventana::on_actionMedium_Filter_triggered()
{
    k->filter(1);
}

void Ventana::on_actionGradient_Y_triggered()
{
    QVector<QRgb> Paleta=ui->Image->image.colorTable();
    for (int y=0;y<ui->Image->image.height()-1; ++y)
    {
        for (int x=0;x<ui->Image->image.width(); ++x)
        {
            int i = ui->Image->image.pixelIndex(x,y);
            QColor color1 = Paleta[i];
            int j = ui->Image->image.pixelIndex(x,y+1);
            QColor color2 = Paleta[j];

            int r=abs(color2.red()-color1.red());
            int g=abs(color2.green()-color1.green());
            int b=abs(color2.blue()-color1.blue());

            int kk=Paleta.indexOf(QColor(r,g,b).rgb());
            if(kk>=0)ui->Image->image.setPixel(x,y,kk);
            else ui->Image->image.setPixel(x,y,0);
        }
    }
    ui->Image->update();
    getHistogram();
}

void Ventana::on_actionGradient_X_triggered()
{
    QVector<QRgb> Paleta=ui->Image->image.colorTable();
    for (int x=0;x<ui->Image->image.width()-1; ++x)
    {
        for (int y=0;y<ui->Image->image.height(); ++y)
        {
            int i = ui->Image->image.pixelIndex(x,y);
            QColor color1 = Paleta[i];
            int j = ui->Image->image.pixelIndex(x+1,y);
            QColor color2 = Paleta[j];

            int r=abs(color2.red()-color1.red());
            int g=abs(color2.green()-color1.green());
            int b=abs(color2.blue()-color1.blue());

            int kk=Paleta.indexOf(QColor(r,g,b).rgb());
            if(kk>=0)ui->Image->image.setPixel(x,y,kk);
            else ui->Image->image.setPixel(x,y,0);
        }
    }
    ui->Image->update();
    getHistogram();

}

void Ventana::on_actionGradient_triggered()
{
    QVector<QRgb> Paleta=ui->Image->image.colorTable();
    for (int x=0;x<ui->Image->image.width()-1; ++x)
    {
        for (int y=0;y<ui->Image->image.height()-1; ++y)
        {
            int i = ui->Image->image.pixelIndex(x,y);
            QColor color1 = Paleta[i];
            int j = ui->Image->image.pixelIndex(x+1,y);
            QColor color2 = Paleta[j];
            int k = ui->Image->image.pixelIndex(x,y+1);
            QColor color3 = Paleta[k];

            int rx=abs(color2.red()-color1.red());
            int gx=abs(color2.green()-color1.green());
            int bx=abs(color2.blue()-color1.blue());

            int ry=abs(color3.red()-color1.red());
            int gy=abs(color3.green()-color1.green());
            int by=abs(color3.blue()-color1.blue());

            float grR = sqrt((rx*rx) + (ry*ry));
            float grG = sqrt((gx*gx) + (gy*gy));
            float grB = sqrt((bx*bx) + (by*by));

            if(grR > 255.0f) grR = 255.0f;
            if(grG > 255.0f) grG = 255.0f;
            if(grB > 255.0f) grB = 255.0f;

            int kk=Paleta.indexOf(QColor((int)grR,(int)grG,(int)grB).rgb());
            if(kk>=0)ui->Image->image.setPixel(x,y,kk);
            else ui->Image->image.setPixel(x,y,0);
        }
    }
    ui->Image->update();
    getHistogram();
}

void Ventana::on_actionReset_Image_triggered()
{
    ui->Image->image=ui->SourceImage->image;
}
